<?php

namespace app\adminapi\logic\setting\lang;

use app\common\logic\BaseLogic;
use app\common\model\lang\{
    LangType,
    LangTranslate,
};
use think\facade\Db;
use app\common\enum\DefaultEnum;
use app\common\enum\LangEnum;
use app\adminapi\service\tools\BuildLangService;
use app\common\cache\FileCache;
use app\common\service\translate\TranslateDriver;

/**
 * 语言逻辑层
 * Class LangLogic
 * @package app\adminapi\logic\setting
 */
class TranslateLogic extends BaseLogic
{


    /**
     * 获取所有类型
     * @return string|string[]
     */
    public static function getClientOptions()
    {
        return LangEnum::getClientOptions();
    }

    /**
     * 译文详情
     * @param array $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function detail(array $params)
    {
        $list = LangTranslate::where([
            ['client_id', '=', $params['client_id']],
            ['code', '=', $params['code']]
        ])
            ->field('id,code,type_id,client_id,after_text')
            ->order('id asc')
            ->select()
            ->toArray();

        $firstInfo = reset($list);
        $info = [
            'id' => $firstInfo['id'],
            'client_id' => $firstInfo['client_id'],
            'code' => $firstInfo['code'],
            'list' => $list
        ];
        return $info;
    }

    /**
     * 新增译文
     * @param array $params
     * @return string|true
     */
    public static function add(array $params)
    {
        $data = [];
        foreach ($params['list'] as $key => $item) {
            $data[] = [
                'code' => $params['code'],
                'client_id' => $params['client_id'],
                'type_id' => $item['type_id'],
                'after_text' => $item['after_text'],
            ];
        }
        Db::startTrans();
        try {
            (new LangTranslate)->saveAll($data);
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return $e->getMessage();
        }
    }

    /**
     * 编辑译文
     * @param array $params
     * @return string|true
     */
    public static function edit(array $params)
    {
        $data = [];
        foreach ($params['list'] as $key => $item) {
            $data[] = [
                'id' => $item['id'] ?? '',
                'type_id' => $item['type_id'],
                'after_text' => $item['after_text'],
            ];
        }

        Db::startTrans();
        try {
            (new LangTranslate)->saveAll($data);
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return $e->getMessage();
        }
    }

    /**
     * @notes 翻译文字
     * @param array $params
     * @return array|false
     */
    public static function autoTranslate(array $params)
    {
        $translateDriver = new TranslateDriver();
        if (!is_null($translateDriver->getError())) {
            self::setError($translateDriver->getError());
            return false;
        }

        $data = [];
        foreach ($params['lang_list'] as $targetCode) {
            $result = $translateDriver
                ->getTranslateText(
                    "",
                    $params['code'],
                    $targetCode
                );
            if (false === $result) {
                self::setError($translateDriver->getError());
                return false;
            }
            $data[$targetCode] = $result;
        }
        return $data;
    }

    /**
     * @notes 删除译文
     * @param $params
     * @return bool
     */
    public static function delete(array $params)
    {
        Db::startTrans();
        try {
            LangTranslate::where([
                ['client_id', '=', $params['client_id']],
                ['code', '=', $params['code']]
            ])->delete();
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    /**
     * 生成语言包
     * @return false|string[]
     */
    public static function buildLangPack()
    {
        try {
            //TODO:一次性获取所有数据
            $buildLangService = new BuildLangService;
            $buildLangService->delBuildDirContent();
            $buildLangService->setBuildFlag(md5('buildLangPack' . time()), true);

            $langTypeList = LangLogic::getLangAll();
            $allTranslate = LangTranslate::field('client_id,type_id,code,after_text')->select()->toArray();

            $clientEnums = LangEnum::getBuildStaticOption();
            // TODO:根据客户端类型区分
            foreach ($clientEnums as $clientItem) {
                // TODO:获取对应数据并生成文件
                foreach ($langTypeList as $langTypeItem){
                    $translateData = $buildLangService->getLangData($allTranslate,$clientItem['value'],$langTypeItem['id']);
                    $buildLangService->buildLangCodeStasic($langTypeItem,$clientItem,$translateData);
                }
            }

            $zipFile = '';
            // 生成压缩包
            if ($buildLangService->getBuildFlag()) {
                $buildLangService->zipFile();
                $buildLangService->delBuildFlag();
                $zipFile = $buildLangService->getDownloadUrl();
            }

            return ['file' => $zipFile];
        } catch (\Exception $e) {
            self::$error = $e->getMessage();
            return false;
        }
    }

    /**
     * @notes 下载语言包
     * @param $fileName
     * @return false|string
     */
    public static function download($fileName)
    {
        $FileCache = new FileCache;
        $cacheFileName = $FileCache->getFile($fileName);
        if (empty($cacheFileName)) {
            self::$error = '请重新生成语言包';
            return false;
        }

        $path = base_path() . '/runtime/lang_pack/' . $fileName;
        if (!file_exists($path)) {
            self::$error = '下载失败';
            return false;
        }

        $FileCache->deleteFile($fileName);
        return $path;
    }
}